package com.payment.system.service.impl;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.bind.JAXBException;

import cn.jiguang.common.resp.APIConnectionException;
import cn.jpush.api.push.PushResult;
import com.payment.common.utils.DateUtils;
import com.payment.common.utils.push.JPushUtil;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.payment.common.base.AjaxResult;
import com.payment.common.constant.Constants;
import com.payment.common.type.LevelStatus;
import com.payment.common.type.MoneyTypeStatus;
import com.payment.common.type.OrderNoPrefix;
import com.payment.common.type.OrderPaymentTradeType;
import com.payment.common.type.OrderStatus;
import com.payment.common.type.PaymentOrderType;
import com.payment.common.utils.RedisPoolUtil;
import com.payment.common.utils.StringUtils;
import com.payment.common.utils.XMLUtils;
import com.payment.system.domain.CompanyMoneyChang;
import com.payment.system.domain.Merchant;
import com.payment.system.domain.MerchantUpgrade;
import com.payment.system.domain.MoneyChange;
import com.payment.system.domain.PaymentOrder;
import com.payment.system.domain.ShoppingOrder;
import com.payment.system.domain.ShoppingOrderProduct;
import com.payment.system.domain.ShoppingOrderShipment;
import com.payment.system.domain.ShoppingProduct;
import com.payment.system.domain.SystemConfig;
import com.payment.system.domain.alipay.AliAppPayConfig;
import com.payment.system.domain.alipay.AliNotifyReqEntity;
import com.payment.system.domain.wxpay.WxAppPay;
import com.payment.system.domain.wxpay.WxNotifyReq;
import com.payment.system.domain.wxpay.WxUnifiedOrderReq;
import com.payment.system.domain.wxpay.WxUnifiedOrderResp;
import com.payment.system.mapper.CompanyMoneyChangMapper;
import com.payment.system.mapper.MerchantMapper;
import com.payment.system.mapper.MerchantParentMapper;
import com.payment.system.mapper.MerchantUpgradeMapper;
import com.payment.system.mapper.MerchantWalletMapper;
import com.payment.system.mapper.MoneyChangeMapper;
import com.payment.system.mapper.PaymentOrderMapper;
import com.payment.system.mapper.ShoppingOrderMapper;
import com.payment.system.mapper.ShoppingOrderProductMapper;
import com.payment.system.mapper.ShoppingOrderShipmentMapper;
import com.payment.system.mapper.ShoppingProductMapper;
import com.payment.system.mapper.SystemConfigMapper;
import com.payment.system.service.IWxAliPayService;

/**
 * @author fuzhili
 * @Description:
 * @date 2019/2/16 9:20
 */
@Service
public class WxAliPayServiceImpl implements IWxAliPayService {
    private static final Logger LOGGER = LoggerFactory.getLogger(WxAliPayServiceImpl.class);

    @Autowired
    private MerchantMapper merchantMapper;
    @Autowired
    private MoneyChangeMapper moneyChangeMapper;
    @Autowired
    private PaymentOrderMapper paymentOrderMapper;
    @Autowired
    private SystemConfigMapper configMapper;
    @Autowired
    private ShoppingOrderMapper shoppingOrderMapper;
    @Autowired
    private ShoppingProductMapper shoppingProductMapper;
    @Autowired
    private ShoppingOrderProductMapper shoppingOrderProductMapper;
    @Autowired
    private ShoppingOrderShipmentMapper shoppingOrderShipmentMapper;
    @Autowired
    private MerchantUpgradeMapper merchantUpgradeMapper;
    @Autowired
    private MerchantWalletMapper merchantWalletMapper;
    @Autowired
    private CompanyMoneyChangMapper companyMoneyChangMapper;
    @Autowired
    private MerchantParentMapper merchantParentMapper;

    private static Logger logger = LoggerFactory.getLogger(WxAliPayServiceImpl.class);
    /**
     * client
     */
    private static CloseableHttpClient client = HttpClientBuilder.create().build();
    /**
     * 微信统一下单
     */
    private final String unifiedOrderUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";

    /**
     * 支付宝网关
     */
    private final String gate = "https://openapi.alipay.com/gateway.do";

    /**
     * 订单预处理
     *
     * @param merchantId
     * @return
     */
    @Override
    public AjaxResult orderPretreatment(String merchantId, Integer orderType) {
        if (StringUtils.isEmpty(merchantId) || orderType == null) {
            return AjaxResult.error(1, "缺失参数");
        }
        Merchant merchant = merchantMapper.selectMerchantById(merchantId);
        if (merchant == null) {
            return AjaxResult.error(2, "获取用户信息失败，该用户不存在");
        }
        String activityUpgrade = "";
        try {
            activityUpgrade = RedisPoolUtil.get("activityUpgrade");
        } catch (Exception e) {
            activityUpgrade = "nil";
        }
        if (activityUpgrade == null || "nil".equals(activityUpgrade) || "".equals(activityUpgrade)) {
            SystemConfig config = configMapper.selectSystemConfigByConfigCode("activityUpgrade");
            RedisPoolUtil.setex("activityUpgrade", config.getConfigValue(), 86400);
            activityUpgrade = config.getConfigValue();
        }
        JSONObject upgradeJson = JSONObject.parseObject(activityUpgrade);
        PaymentOrder p = new PaymentOrder();
        String orderNo = StringUtils.createNum();
        if (PaymentOrderType.SIX.getCode().equals(orderType)) {
            if (merchant.getLevel().compareTo(2) > -1) {
                return AjaxResult.error(3, "您的等级已超过vip，无需充值");
            }
            // 充值升级
            List<PaymentOrder> orderList = paymentOrderMapper.selectPaymentOrderListByMerchantIdAndStatus(merchantId, 1,
                    PaymentOrderType.SIX.getCode());
            if (orderList != null && orderList.size() > 0) {
                return AjaxResult.error(4, "您已充值过Vip，请勿重复购买");
            }
            p.setOrderType(PaymentOrderType.SIX.getCode());
            p.setOrderNo(orderNo);
            p.setAmountMoney(upgradeJson.getBigDecimal("upgrade"));
        } else if (PaymentOrderType.NINE.getCode().equals(orderType)) {
            // 卡测评
            p.setOrderType(PaymentOrderType.NINE.getCode());
            p.setOrderNo(OrderNoPrefix.CARD_SHANGHU.getCode() + orderNo);
            p.setAmountMoney(upgradeJson.getBigDecimal("cardEvaluate"));
        }
        String orderId = StringUtils.randomUUID();
        p.setId(orderId);
        p.setMerchantId(merchant.getId());
        p.setMerchantName(merchant.getMerchantCnName());
        p.setOrderStatus(0);
        p.setCreditNumber(merchant.getBankAccount());
        p.setBankName(merchant.getBankName());
        p.setCostRateMoney(new BigDecimal("0"));
        p.setRateMoney(new BigDecimal("0"));
        p.setProfitMoney(new BigDecimal("0"));
        p.setClearingStatus(1);
        paymentOrderMapper.insertPaymentOrder(p);
        return AjaxResult.successAndData("订单预处理成功", orderId);
    }

    /**
     * 微信支付 ,支付宝支付
     *
     * @param merchantId
     * @param orderId
     * @return
     */
    @Override
    public AjaxResult wxAliPay(String merchantId, String orderId, String mode) {
        if (StringUtils.isEmpty(merchantId) || StringUtils.isEmpty(mode)) {
            return AjaxResult.error(1, "缺失参数");
        }
        Merchant merchant = merchantMapper.selectMerchantById(merchantId);
        if (merchant == null) {
            return AjaxResult.error(2, "该用户不存在");
        }
        PaymentOrder order = paymentOrderMapper.selectPaymentOrderById(orderId);
        if (order == null) {
            return AjaxResult.error(3, "该订单不存在");
        }
        if (!order.getOrderStatus().equals(0)) {
            return AjaxResult.error(4, "该订单不是待支付状态");
        }
        // 判断是微信支付还是支付宝>>普通商品还是升级商品
        if (StringUtils.equals(mode, OrderPaymentTradeType.WXPAY.getCode())) {
            // 微信支付
            /*order.setAcqCode("1");
            order.setAcqId("1");
            order.setAcqName("微信");
            paymentOrderMapper.updatePaymentOrder(order);
            Integer amountMoney = order.getAmountMoney().multiply(new BigDecimal("100")).intValue();
            // 创建订单 //统一下单+签名
            WxUnifiedOrderReq unifiedOrderReq = null;
            try {
                unifiedOrderReq = new WxUnifiedOrderReq(Constants.MERCHANT_UPGRADE, order.getOrderNo(), amountMoney,
                        "127.0.0.1");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            WxUnifiedOrderResp unifiedOrderResponse = new WxUnifiedOrderResp();
            try {
                unifiedOrderResponse = unifiedOrder(unifiedOrderReq);
                return AjaxResult.successAndData("微信签名成功", new WxAppPay(unifiedOrderResponse));
            } catch (JAXBException | IOException e) {
                e.printStackTrace();
                logger.info("统一下单+签名失败");
                return AjaxResult.error("微信统一下单+签名失败");
            } catch (Exception e) {
                e.printStackTrace();
                logger.info("统一下单+签名发生异常");
                return AjaxResult.error("微信统一下单+签名发生异常");
            }*/
            return AjaxResult.error("微信支付暂不支持");
        } else if (StringUtils.equals(mode, OrderPaymentTradeType.ZFB.getCode())) {
            // 支付宝支付、
            order.setAcqCode("2");
            order.setAcqId("2");
            order.setAcqName("支付宝");
            paymentOrderMapper.updatePaymentOrder(order);
            String r = saveOrderByZFB(order);
            logger.info("支付宝返回:" + r);
            return AjaxResult.successAndData("支付宝返回:", r);

        } else {
            return AjaxResult.error("没有对应的支付方式");
        }
    }

    @Override
    public AjaxResult wxAliPaySH(String merchantId, String orderId, String mode) {
        if (StringUtils.isEmpty(merchantId) || StringUtils.isEmpty(mode)) {
            return AjaxResult.error(1, "缺失参数");
        }
        Merchant merchant = merchantMapper.selectMerchantById(merchantId);
        if (merchant == null) {
            return AjaxResult.error(2, "该用户不存在");
        }
        ShoppingOrder order = shoppingOrderMapper.selectShoppingOrderById(orderId);
        if (order == null) {
            return AjaxResult.error(3, "该订单不存在");
        }
        if (!order.getOrderStatus().equals("10A")) {
            return AjaxResult.error(4, "该订单不是待支付状态");
        }
        // 判断是微信支付还是支付宝>>普通商品还是升级商品
        if (StringUtils.equals(mode, OrderPaymentTradeType.WXPAY.getCode())) {
            // 微信支付
            // 微信支付
            // 保存支付方式
            order.setPayMode("10A");

            shoppingOrderMapper.updateShoppingOrder(order);
            BigDecimal amount = order.getPayAmount();
            // 乘以100(单位：分)
            Integer amountMoney = amount.multiply(new BigDecimal(100)).intValue();
            ;
            // 创建订单 //统一下单+签名
            WxUnifiedOrderReq unifiedOrderReq = null;
            try {
                unifiedOrderReq = new WxUnifiedOrderReq(Constants.SHOPPING, order.getOrderNumber(), amountMoney,
                        "127.0.0.1");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            WxUnifiedOrderResp unifiedOrderResponse = new WxUnifiedOrderResp();
            try {
                unifiedOrderResponse = unifiedOrder(unifiedOrderReq);
                return AjaxResult.successAndData("微信签名成功", new WxAppPay(unifiedOrderResponse));
            } catch (JAXBException | IOException e) {
                logger.info("统一下单+签名失败");
                e.printStackTrace();
                return AjaxResult.error("微信统一下单+签名失败");
            } catch (Exception e) {
                e.printStackTrace();
                logger.info("统一下单+签名发生异常");
                return AjaxResult.error("微信统一下单+签名发生异常");
            }
        } else if (StringUtils.equals(mode, OrderPaymentTradeType.ZFB.getCode())) {
            // 支付宝支付、
            // 保存支付方式
            order.setPayMode("10B");
            order.setPaymentTime(new Date());
            shoppingOrderMapper.updateShoppingOrder(order);
            String r = saveOrderByZFBSH(order);
            logger.info("支付宝返回:" + r);
            return AjaxResult.successAndData("支付宝返回:", r);

        } else {
            return AjaxResult.error("没有对应的支付方式");
        }
    }

    private String saveOrderByZFB(PaymentOrder order) {
        // 商户网站唯一订单号,商品名称,总金额,商品详情
        double totalAmount = order.getAmountMoney().setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        return createParamString(order.getOrderNo(), Constants.SHOPPING_REMARK, totalAmount, Constants.SHOPPING_REMARK);
    }

    // app上线审核的商城商品
    private String saveOrderByZFBSH(ShoppingOrder order) {
        // 商户网站唯一订单号,商品名称,总金额,商品详情
        double totalAmount = order.getPayAmount().setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        return createParamString(order.getOrderNumber(), Constants.SHOPPING, totalAmount, Constants.SHOPPING);
    }

    /**
     * 计算分多少钱
     *
     * @param order 订单对象
     */
    public void orderProfit(PaymentOrder order, String parentPhone) {
        /******************** 获取费率配置开始 **********************/
        LOGGER.info("开始清分，订单ID={}", order.getId());
        String commission = "";
        try {
            commission = RedisPoolUtil.get("commission");
        } catch (Exception e) {
            commission = "nil";
        }
        if (commission == null || "nil".equals(commission) || "".equals(commission)) {
            SystemConfig config = configMapper.selectSystemConfigByConfigCode("commission");
            RedisPoolUtil.setex("commission", config.getConfigValue(), 86400);
            commission = config.getConfigValue();
        }
        JSONObject jsonConfig = JSONObject.parseObject(commission);
        /******************** 获取费率配置开始 **********************/
        if (order.getOrderType().equals(6)) {
            // 充值升级
            vipCommission(parentPhone, order.getId(), jsonConfig, order.getAmountMoney());
        } else if (order.getOrderType().equals(9)) {
            // 卡测评
            commission(parentPhone, order.getId(), jsonConfig, order.getAmountMoney(), "cardEvaluate",
                    MoneyTypeStatus.I.getCode());
        } else if (order.getOrderType().equals(10)) {
            // 境外
            commission(parentPhone, order.getId(), jsonConfig, order.getAmountMoney(), "abroadExchange",
                    MoneyTypeStatus.J.getCode());
        }
    }

    private void commission(String parentPhone, String orderId, JSONObject jsonConfig, BigDecimal amountMoney,
                            String commissionType, String moenyType) {
        // TODO Auto-generated method stub
        JSONObject json = jsonConfig.getJSONObject(commissionType);
        BigDecimal max = json.getBigDecimal("max");
        BigDecimal hasProportion = BigDecimal.ZERO;
        BigDecimal pmoney = BigDecimal.ZERO;
        while (true) {
            Merchant parentUser = merchantMapper.selectMerchantByPhone(parentPhone);
            if (hasProportion.compareTo(max) >= 0 || parentUser == null) {
                CompanyMoneyChang moneyChang = new CompanyMoneyChang();
                moneyChang.setId(StringUtils.randomUUID());
                moneyChang.setEntryMoney(amountMoney);
                moneyChang.setProfitMoney(pmoney);
                moneyChang.setMoney(amountMoney.subtract(pmoney).setScale(3, BigDecimal.ROUND_DOWN));
                moneyChang.setOrderId(orderId);
                moneyChang.setCreateTime(new Date());
                companyMoneyChangMapper.insertCompanyMoneyChang(moneyChang);
                break;
            }
            BigDecimal proportion = json.getBigDecimal(parentUser.getLevel().toString());
            proportion = proportion.subtract(hasProportion);
            if (proportion.compareTo(BigDecimal.ZERO) == 1) {
                hasProportion = proportion;
                BigDecimal moeny = amountMoney.multiply(proportion).setScale(2, BigDecimal.ROUND_DOWN);
                pmoney = pmoney.add(moeny);
                int i = merchantWalletMapper.increaseInRevenue(parentUser.getId(), moeny);
                if (i > 0) {
                    saveMoenyChange(moeny, orderId, parentUser.getId(), moenyType, "10C");
                }
            }
            parentPhone = parentUser.getParentMerchantPhone();
        }
    }

    public void vipCommission(String parentPhone, String orderId, JSONObject jsonConfig, BigDecimal orderMoney) {
        JSONObject fanxian = jsonConfig.getJSONObject("vipFanxian");
        Integer fanXianIndex = 0;
        BigDecimal hasMoeny = BigDecimal.ZERO;
        BigDecimal teamMoney = BigDecimal.ZERO;
        while (true) {
            Merchant parentUser = merchantMapper.selectMerchantByPhone(parentPhone);
            if ((hasMoeny.compareTo(fanxian.getBigDecimal("max")) == 0
                    && teamMoney.compareTo(BigDecimal.valueOf(50)) == 0) || parentUser == null) {
                CompanyMoneyChang moneyChang = new CompanyMoneyChang();
                moneyChang.setId(StringUtils.randomUUID());
                moneyChang.setEntryMoney(orderMoney);
                moneyChang.setProfitMoney(hasMoeny);
                moneyChang.setMoney(orderMoney.subtract(hasMoeny).setScale(3, BigDecimal.ROUND_DOWN));
                moneyChang.setOrderId(orderId);
                moneyChang.setCreateTime(new Date());
                companyMoneyChangMapper.insertCompanyMoneyChang(moneyChang);
                break;
            }
            if (parentUser.getLevel() > 1 && parentUser.getLevel() < 6) {
                // 普通充值分佣
                BigDecimal vipMoney = fanxian.getBigDecimal(fanXianIndex.toString());
                if (vipMoney.compareTo(BigDecimal.ZERO) == 1) {
                    hasMoeny = hasMoeny.add(vipMoney);
                    fanXianIndex++;
                    int i = merchantWalletMapper.increaseInRevenue(parentUser.getId(), vipMoney);
                    if (i > 0) {
                        saveMoenyChange(vipMoney, orderId, parentUser.getId(), MoneyTypeStatus.C.getCode(), "10C");
                    }
                }
                Integer vipNum = merchantParentMapper.selectCongZhiNumByLevelAndParentPhone(parentUser.getPhone(), 2);
                if (vipNum >= 10 && vipNum < 20 && parentUser.getLevel().compareTo(3) < 0) {
                    Merchant upmer = new Merchant();
                    upmer.setId(parentUser.getId());
                    upmer.setLevel(3);
                    upmer.setIsCompany("10E");
                    merchantMapper.updateMerchant(upmer);
                    MerchantUpgrade merchantUpgrade = new MerchantUpgrade();
                    merchantUpgrade.setId(StringUtils.randomUUID());
                    merchantUpgrade.setPhone(parentUser.getPhone());
                    merchantUpgrade.setLevel(3);
                    merchantUpgrade.setCreateTime(new Date());
                    merchantUpgrade.setMerchantName(parentUser.getMerchantCnName());
                    merchantUpgrade.setType("10B");
                    merchantUpgrade.setMerchantId(parentUser.getId());
                    merchantUpgradeMapper.insertMerchantUpgrade(merchantUpgrade);
                } else if (vipNum >= 20 && vipNum < 50 && parentUser.getLevel().compareTo(4) < 0) {
                    Merchant upmer = new Merchant();
                    upmer.setId(parentUser.getId());
                    upmer.setLevel(4);
                    upmer.setIsCompany("10E");
                    merchantMapper.updateMerchant(upmer);
                    MerchantUpgrade merchantUpgrade = new MerchantUpgrade();
                    merchantUpgrade.setId(StringUtils.randomUUID());
                    merchantUpgrade.setPhone(parentUser.getPhone());
                    merchantUpgrade.setLevel(3);
                    merchantUpgrade.setCreateTime(new Date());
                    merchantUpgrade.setMerchantName(parentUser.getMerchantCnName());
                    merchantUpgrade.setType("10B");
                    merchantUpgrade.setMerchantId(parentUser.getId());
                    merchantUpgradeMapper.insertMerchantUpgrade(merchantUpgrade);
                } else if (vipNum >= 50 && vipNum < 100 && parentUser.getLevel().compareTo(5) < 0) {
                    Merchant upmer = new Merchant();
                    upmer.setId(parentUser.getId());
                    upmer.setLevel(5);
                    upmer.setIsCompany("10E");
                    merchantMapper.updateMerchant(upmer);
                    MerchantUpgrade merchantUpgrade = new MerchantUpgrade();
                    merchantUpgrade.setId(StringUtils.randomUUID());
                    merchantUpgrade.setPhone(parentUser.getPhone());
                    merchantUpgrade.setLevel(3);
                    merchantUpgrade.setCreateTime(new Date());
                    merchantUpgrade.setMerchantName(parentUser.getMerchantCnName());
                    merchantUpgrade.setType("10B");
                    merchantUpgrade.setMerchantId(parentUser.getId());
                    merchantUpgradeMapper.insertMerchantUpgrade(merchantUpgrade);
                } else if (vipNum >= 100 && parentUser.getLevel().compareTo(6) < 0) {
                    Merchant upmer = new Merchant();
                    upmer.setId(parentUser.getId());
                    upmer.setLevel(6);
                    upmer.setIsCompany("10E");
                    merchantMapper.updateMerchant(upmer);
                    MerchantUpgrade merchantUpgrade = new MerchantUpgrade();
                    merchantUpgrade.setId(StringUtils.randomUUID());
                    merchantUpgrade.setPhone(parentUser.getPhone());
                    merchantUpgrade.setLevel(3);
                    merchantUpgrade.setCreateTime(new Date());
                    merchantUpgrade.setMerchantName(parentUser.getMerchantCnName());
                    merchantUpgrade.setType("10B");
                    merchantUpgrade.setMerchantId(parentUser.getId());
                    merchantUpgradeMapper.insertMerchantUpgrade(merchantUpgrade);
                }
            } else if (parentUser.getLevel().equals(6)) {
                // 核心合伙人正常分钱加团队团里奖
                BigDecimal money = fanxian.getBigDecimal("max").subtract(hasMoeny);
                if (fanXianIndex>0) {
                	if (money.compareTo(BigDecimal.ZERO)<0){
                		money = BigDecimal.ZERO;
                	}
                	int num = merchantParentMapper.selectTeamNumByPhoneAndLevel(parentUser.getPhone(),
                            parentUser.getLevel());
                    if (num >= 6 && num <= 30 && teamMoney.compareTo(BigDecimal.valueOf(20)) < 0) {
                        teamMoney = BigDecimal.valueOf(20);
                        money = money.add(teamMoney).setScale(3, BigDecimal.ROUND_DOWN);
                    } else if (num >= 31 && num <= 150 && teamMoney.compareTo(BigDecimal.valueOf(30)) < 0) {
                        money = money.add(BigDecimal.valueOf(30).subtract(teamMoney)).setScale(3,
                                BigDecimal.ROUND_DOWN);
                        teamMoney = BigDecimal.valueOf(30);
                    } else if (num >= 151 && num <= 300 && teamMoney.compareTo(BigDecimal.valueOf(40)) < 0) {
                        money = money.add(BigDecimal.valueOf(40).subtract(teamMoney)).setScale(3,
                                BigDecimal.ROUND_DOWN);
                        teamMoney = BigDecimal.valueOf(40);
                    } else if (num >= 301 && num <= 600 && teamMoney.compareTo(BigDecimal.valueOf(45)) < 0) {
                        money = money.add(BigDecimal.valueOf(45).subtract(teamMoney)).setScale(3,
                                BigDecimal.ROUND_DOWN);
                        teamMoney = BigDecimal.valueOf(45);
                    } else if (num >= 601 && teamMoney.compareTo(BigDecimal.valueOf(50)) < 0) {
                        money = money.add(BigDecimal.valueOf(50).subtract(teamMoney)).setScale(3,
                                BigDecimal.ROUND_DOWN);
                        teamMoney = BigDecimal.valueOf(50);
                    }
                }
                if (money.compareTo(BigDecimal.ZERO) == 1) {
                    hasMoeny = hasMoeny.add(money);
                    int i = merchantWalletMapper.increaseInRevenue(parentUser.getId(), money);
                    if (i > 0) {
                        saveMoenyChange(money, orderId, parentUser.getId(), MoneyTypeStatus.C.getCode(), "10C");
                    }
                }
                fanXianIndex = 3;
            }
            parentPhone = parentUser.getParentPhone();
        }
    }

    private void saveMoenyChange(BigDecimal moeny, String orderId, String userId, String moenyType, String status) {
        // TODO Auto-generated method stub
        MoneyChange m = new MoneyChange();
        m.setCreateTime(new Date());
        m.setId(StringUtils.randomUUID());
        m.setMoneyType(moenyType);
        m.setPaymentOrderId(orderId);
        m.setStatus(status);
        m.setUserId(userId);
        m.setTrxAmt(moeny);
        moneyChangeMapper.insertMoneyChange(m);
        //推送
        try {
            pushAll(userId, moeny.toString(), orderId);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("极光推送失败,{}",e);
        }
    }

    public void partnerCommission(String parentPhone, String orderId, JSONObject jsonConfig, BigDecimal orderMoney) {
        JSONObject fanxian = jsonConfig.getJSONObject("PartnerFanxian");
        BigDecimal hashMoney = BigDecimal.ZERO;
        BigDecimal teamMoney = BigDecimal.ZERO;
        int k = 0;
        while (true) {
            Merchant parentUser = merchantMapper.selectMerchantByPhone(parentPhone);
            if (parentUser == null) {
                hashMoney = hashMoney.add(teamMoney);
                CompanyMoneyChang moneyChang = new CompanyMoneyChang();
                moneyChang.setId(StringUtils.randomUUID());
                moneyChang.setEntryMoney(orderMoney);
                moneyChang.setProfitMoney(hashMoney);
                moneyChang.setMoney(orderMoney.subtract(hashMoney).setScale(3, BigDecimal.ROUND_DOWN));
                moneyChang.setOrderId(orderId);
                moneyChang.setCreateTime(new Date());
                companyMoneyChangMapper.insertCompanyMoneyChang(moneyChang);
                break;
            }
            BigDecimal vipMoney = fanxian.getBigDecimal(k + "");
            vipMoney = orderMoney.multiply(vipMoney);
            if (vipMoney.compareTo(BigDecimal.ZERO) == 1) {
                k = k + 1;
            }
            hashMoney = hashMoney.add(vipMoney);
            String status = "10A";
            if (parentUser.getLevel().equals(6) && k>0) {
                int num = merchantParentMapper.selectTeamNumByPhoneAndLevel(parentUser.getPhone(),
                        parentUser.getLevel());
                if (num >= 6 && num <= 30 && teamMoney.compareTo(BigDecimal.valueOf(150)) < 0) {
                    teamMoney = BigDecimal.valueOf(150);
                    vipMoney = vipMoney.add(teamMoney).setScale(3, BigDecimal.ROUND_DOWN);
                } else if (num >= 31 && num <= 150 && teamMoney.compareTo(BigDecimal.valueOf(200)) < 0) {
                    vipMoney = vipMoney.add(BigDecimal.valueOf(200).subtract(teamMoney)).setScale(3,
                            BigDecimal.ROUND_DOWN);
                    teamMoney = BigDecimal.valueOf(200);
                } else if (num >= 151 && num <= 300 && teamMoney.compareTo(BigDecimal.valueOf(240)) < 0) {
                    vipMoney = vipMoney.add(BigDecimal.valueOf(240).subtract(teamMoney)).setScale(3,
                            BigDecimal.ROUND_DOWN);
                    teamMoney = BigDecimal.valueOf(240);
                } else if (num >= 301 && num <= 600 && teamMoney.compareTo(BigDecimal.valueOf(280)) < 0) {
                    vipMoney = vipMoney.add(BigDecimal.valueOf(280).subtract(teamMoney)).setScale(3,
                            BigDecimal.ROUND_DOWN);
                    teamMoney = BigDecimal.valueOf(280);
                } else if (num >= 601 && teamMoney.compareTo(BigDecimal.valueOf(350)) < 0) {
                    vipMoney = vipMoney.add(BigDecimal.valueOf(350).subtract(teamMoney)).setScale(3,
                            BigDecimal.ROUND_DOWN);
                    teamMoney = BigDecimal.valueOf(350);
                }
                status = "10C";
            }
            if (vipMoney.compareTo(BigDecimal.ZERO) == 1) {
                saveMoenyChange(vipMoney, orderId, parentUser.getId(), MoneyTypeStatus.D.getCode(), status);
                if (status.equals("10C")) {
                    merchantWalletMapper.increaseInRevenue(parentUser.getId(), vipMoney);
                }
            }
            parentPhone = parentUser.getParentPhone();
        }

    }

    /**
     * 微信异步通知处理方法
     */
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    @Override
    public synchronized boolean wxNotify(String notityXml) {
        WxNotifyReq wxNotifyReq = null;
        wxNotifyReq = (WxNotifyReq) XMLUtils.xml2Obj(notityXml, WxNotifyReq.class);
        String orderPrefix = wxNotifyReq.getOutTradeNo().substring(0, 3);
        boolean aBoolean = false;
        if (StringUtils.equals(orderPrefix, OrderNoPrefix.PREFIX_SHANGHU.getCode())) {
            // 上架商城
            aBoolean = getBooleanSH(wxNotifyReq);
        } else if (StringUtils.equals(orderPrefix, OrderNoPrefix.CARD_SHANGHU.getCode())) {
            // 卡测评
            aBoolean = getBooleanCardEvaluate(wxNotifyReq);
        } else {
            // 充值升级
            aBoolean = getBoolean(wxNotifyReq);
        }
        return aBoolean;
    }

    // 卡测评充值回调
    private boolean getBooleanCardEvaluate(WxNotifyReq wxNotifyReq) {
        if (wxNotifyReq != null && !StringUtils.isEmpty(wxNotifyReq.getResultCode())
                && !StringUtils.isEmpty(wxNotifyReq.getOutTradeNo())) {
            PaymentOrder order = paymentOrderMapper.selectPaymentOrderByOrderNo(wxNotifyReq.getOutTradeNo());
            List<MoneyChange> moneyChangeList = moneyChangeMapper.selectMoneyChangeListByOrderId(order.getId());
            if (1 == order.getOrderStatus() || moneyChangeList.size() > 0) {
                return true;
            }
            switch (wxNotifyReq.getResultCode().toLowerCase()) {
                case "success": // 交易成功 修改订单状态
                    order.setOrderStatus(1);
                    order.setCompleteTime(new Date());
                    paymentOrderMapper.updatePaymentOrder(order);
                    Merchant mer = merchantMapper.selectMerchantById(order.getMerchantId());
                    orderProfit(order, mer.getPhone());
                    break;
                case "fail":
                    // 失败
                    order.setOrderStatus(2);
                    paymentOrderMapper.updatePaymentOrder(order);
                    break;
                default:
                    break;
            }
            return true;
        } else {
            return false;
        }
    }

    /**
     * 积分商城微信支付回调
     *
     * @param wxNotifyReq
     * @return
     */
    private boolean getBoolean(WxNotifyReq wxNotifyReq) {
        if (wxNotifyReq != null && !StringUtils.isEmpty(wxNotifyReq.getResultCode())
                && !StringUtils.isEmpty(wxNotifyReq.getOutTradeNo())) {
            PaymentOrder order = paymentOrderMapper.selectPaymentOrderByOrderNo(wxNotifyReq.getOutTradeNo());
            List<MoneyChange> moneyChangeList = moneyChangeMapper.selectMoneyChangeListByOrderId(order.getOrderNo());
            if (1 == order.getOrderStatus() || moneyChangeList.size() > 0) {
                return true;
            }
            switch (wxNotifyReq.getResultCode().toLowerCase()) {
                case "success": // 交易成功 修改订单状态
                    order.setOrderStatus(1);
                    order.setCompleteTime(new Date());
                    paymentOrderMapper.updatePaymentOrder(order);
                    // 保存升级记录
                    String parentPhone = saveMerchantUpgrade(order.getMerchantId(), "2");
                    // 升级分润
                    orderProfit(order, parentPhone);
                    break;
                case "fail":
                    // 失败
                    order.setOrderStatus(2);
                    paymentOrderMapper.updatePaymentOrder(order);
                    break;
                default:
                    break;
            }
            return true;
        } else {
            return false;
        }
    }

    /**
     * app上架用的商城微信支付回调
     *
     * @param wxNotifyReq
     * @return
     */
    private boolean getBooleanSH(WxNotifyReq wxNotifyReq) {
        if (wxNotifyReq != null && !StringUtils.isEmpty(wxNotifyReq.getResultCode())
                && !StringUtils.isEmpty(wxNotifyReq.getOutTradeNo())) {
            ShoppingOrder order = shoppingOrderMapper.selectShoppingOrderByOrderNumner(wxNotifyReq.getOutTradeNo());
            List<MoneyChange> moneyChangeList = moneyChangeMapper.selectMoneyChangeListByOrderId(order.getId());
            if (StringUtils.equals(order.getOrderStatus(), OrderStatus.PAID.getCode()) || moneyChangeList.size() > 0) {
                return true;
            }
            switch (wxNotifyReq.getResultCode().toLowerCase()) {
                // 交易成功 修改订单状态
                case "success":
                    // 交易成功 修改订单状态
                    order.setOrderStatus(OrderStatus.PAID.getCode());
                    order.setPaymentTime(new Date());
                    shoppingOrderMapper.updateShoppingOrder(order);
                    // 添加销量
                    addSales(order);
                    // 修改配送表 是否需要配送
                    if (order.getDelivery().equals("10B")) {
                        ShoppingOrderShipment shipment = shoppingOrderShipmentMapper
                                .selectShoppingOrderShipmentByOrderId(order.getId());
                        shipment.setDel(0);
                        shoppingOrderShipmentMapper.updateShoppingOrderShipment(shipment);
                    }
                    break;
                case "fail":
                    // 失败
                    order.setOrderStatus(OrderStatus.FAIL.getCode());
                    shoppingOrderMapper.updateShoppingOrder(order);
                    break;
                default:
                    break;
            }
            return true;
        } else {
            return false;
        }
    }

    /**
     * 保存升级记录
     *
     * @param merchantId
     * @return 用户推荐人手机号
     */
    public String saveMerchantUpgrade(String merchantId, String level) {
        Merchant merchant = merchantMapper.selectMerchantById(merchantId);
        if (merchant.getLevel() < LevelStatus.TWO.getCode()) {
            merchantMapper.updateMerchantLevelById(merchantId, Integer.parseInt(level));
        }
        String vipReturnConfig = "";
        try {
            vipReturnConfig = RedisPoolUtil.get("vipReturnConfig");
        } catch (Exception e) {
            vipReturnConfig = "nil";
        }
        if (vipReturnConfig == null || "nil".equals(vipReturnConfig) || "".equals(vipReturnConfig)) {
            SystemConfig config = configMapper.selectSystemConfigByConfigCode("vipReturnConfig");
            RedisPoolUtil.setex("vipReturnConfig", config.getConfigValue(), 86400);
            vipReturnConfig = config.getConfigValue();
        }
        JSONObject jsonConfig = JSONObject.parseObject(vipReturnConfig);
        merchantWalletMapper.increaseVipMoney(merchantId, jsonConfig.getBigDecimal("money"));
        MerchantUpgrade merchantUpgrade = new MerchantUpgrade();
        merchantUpgrade.setId(StringUtils.randomUUID());
        merchantUpgrade.setPhone(merchant.getPhone());
        merchantUpgrade.setLevel(Integer.parseInt(level));
        merchantUpgrade.setCreateTime(new Date());
        merchantUpgrade.setMerchantName(merchant.getMerchantCnName());
        merchantUpgrade.setType("10B");
        merchantUpgrade.setMerchantId(merchant.getId());
        merchantUpgradeMapper.insertMerchantUpgrade(merchantUpgrade);
        return merchant.getParentPhone();
    }

    /**
     * 支付宝异步通知处理方法
     *
     * @param aliNotifyReqEntity
     * @return <pre>
     */
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    @Override
    public synchronized String aliNotify(AliNotifyReqEntity aliNotifyReqEntity) {
        String result = "fail";
        if (aliNotifyReqEntity != null && !StringUtils.isEmpty(aliNotifyReqEntity.getOut_trade_no())) {
            String orderPrefix = aliNotifyReqEntity.getOut_trade_no().substring(0, 3);
            if (StringUtils.equals(orderPrefix, OrderNoPrefix.PREFIX_SHANGHU.getCode())) {
                result = getStringSH(aliNotifyReqEntity);
            } else if (StringUtils.equals(orderPrefix, OrderNoPrefix.CARD_SHANGHU.getCode())) {
                // 卡测评
                result = getStringCardEvaluate(aliNotifyReqEntity);
            } else {
                result = getString(aliNotifyReqEntity);
            }
        }
        return result;
    }

    /**
     * 卡测评 支付宝异步回调
     *
     * @param aliNotifyReqEntity
     * @return
     */
    private String getStringCardEvaluate(AliNotifyReqEntity aliNotifyReqEntity) {

        if (aliNotifyReqEntity != null && !StringUtils.isEmpty(aliNotifyReqEntity.getOut_trade_no())) {
            PaymentOrder order = paymentOrderMapper.selectPaymentOrderByOrderNo(aliNotifyReqEntity.getOut_trade_no());
            List<MoneyChange> moneyChangeList = moneyChangeMapper.selectMoneyChangeListByOrderId(order.getId());
            if (1 == order.getOrderStatus() || moneyChangeList.size() > 0) {
                return "sucess";
            }
            switch (aliNotifyReqEntity.getTrade_status()) {
                case "TRADE_SUCCESS":// 支付成功
                    order.setOrderStatus(1);
                    order.setCompleteTime(new Date());
                    paymentOrderMapper.updatePaymentOrder(order);
                    Merchant mer = merchantMapper.selectMerchantById(order.getMerchantId());
                    orderProfit(order, mer.getPhone());
                    break;
                default:
                    order.setOrderStatus(2);
                    paymentOrderMapper.updatePaymentOrder(order);
                    break;
            }
            return "sucess";
        } else {
            return "fail";
        }
    }

    /**
     * 积分商城微信支付回调
     *
     * @param aliNotifyReqEntity
     * @return
     */
    private String getString(AliNotifyReqEntity aliNotifyReqEntity) {
        if (aliNotifyReqEntity != null && !StringUtils.isEmpty(aliNotifyReqEntity.getOut_trade_no())) {
            PaymentOrder order = paymentOrderMapper.selectPaymentOrderByOrderNo(aliNotifyReqEntity.getOut_trade_no());
            List<MoneyChange> moneyChangeList = moneyChangeMapper.selectMoneyChangeListByOrderId(order.getId());
            if (1 == order.getOrderStatus() || moneyChangeList.size() > 0) {
                return "sucess";
            }
            switch (aliNotifyReqEntity.getTrade_status()) {
                case "TRADE_SUCCESS":// 支付成功
                    order.setOrderStatus(1);
                    order.setCompleteTime(new Date());
                    paymentOrderMapper.updatePaymentOrder(order);
                    // 保存升级记录
                    String parentPhone = saveMerchantUpgrade(order.getMerchantId(), "2");
                    // 升级分润
                    orderProfit(order, parentPhone);
                    break;
                default:
                    order.setOrderStatus(2);
                    paymentOrderMapper.updatePaymentOrder(order);
                    break;
            }
            return "sucess";
        } else {
            return "fail";
        }
    }

    /**
     * app上架用的商城微信支付回调
     *
     * @param aliNotifyReqEntity
     * @return
     */
    private String getStringSH(AliNotifyReqEntity aliNotifyReqEntity) {
        if (aliNotifyReqEntity != null && !StringUtils.isEmpty(aliNotifyReqEntity.getOut_trade_no())) {
            ShoppingOrder order = shoppingOrderMapper
                    .selectShoppingOrderByOrderNumner(aliNotifyReqEntity.getOut_trade_no());
            List<MoneyChange> moneyChangeList = moneyChangeMapper.selectMoneyChangeListByOrderId(order.getId());
            if (StringUtils.equals(order.getOrderStatus(), OrderStatus.PAID.getCode()) || moneyChangeList.size() > 0) {
                return "sucess";
            }
            switch (aliNotifyReqEntity.getTrade_status()) {
                // 支付成功
                case "TRADE_SUCCESS":
                    order.setOrderStatus(OrderStatus.PAID.getCode());
                    order.setPaymentTime(new Date());
                    shoppingOrderMapper.updateShoppingOrder(order);
                    // 添加销量
                    addSales(order);
                    // 修改配送表 是否需要配送
                    if (order.getDelivery().equals("10B")) {
                        ShoppingOrderShipment shipment = shoppingOrderShipmentMapper
                                .selectShoppingOrderShipmentByOrderId(order.getId());
                        shipment.setDel(0);
                        shoppingOrderShipmentMapper.updateShoppingOrderShipment(shipment);
                    }
                    break;
                default:
                    order.setOrderStatus(OrderStatus.FAIL.getCode());
                    shoppingOrderMapper.updateShoppingOrder(order);
                    break;
            }
            return "sucess";
        } else {
            return "fail";
        }
    }

    private void addSales(ShoppingOrder order) {
        List<ShoppingOrderProduct> list = shoppingOrderProductMapper.selectShoppingOrderProductByOrderId(order.getId());
        for (ShoppingOrderProduct orderProduct : list) {
            // 查询
            ShoppingProduct product = shoppingProductMapper.selectShoppingProductById(orderProduct.getProductId());
            if (product != null) {
                product.setSales(product.getSales() + 1);
                shoppingProductMapper.updateShoppingProduct(product);
            }
        }
    }

    /**
     * 统一下单
     *
     * @return
     * @throws IOException
     * @throws JAXBException
     */
    private WxUnifiedOrderResp unifiedOrder(WxUnifiedOrderReq unifiedOrderRequest) throws JAXBException, IOException {
        String xml = XMLUtils.obj2XML(unifiedOrderRequest);
        String result = post(unifiedOrderUrl, xml);
        System.out.println(result);
        return (WxUnifiedOrderResp) XMLUtils.xml2Obj(result, WxUnifiedOrderResp.class);
    }

    /**
     * 发送请求
     *
     * @param url
     * @param param
     * @return
     * @throws ClientProtocolException
     * @throws IOException
     */
    private static String post(String url, String param) throws ClientProtocolException, IOException {
        HttpPost post = new HttpPost(url);
        if (param != null) {
            post.setEntity(new StringEntity(param, "UTF-8"));
        }
        CloseableHttpResponse response = client.execute(post);
        HttpEntity entity = response.getEntity();
        String result = EntityUtils.toString(entity, "utf-8");
        post.releaseConnection();
        response.close();
        return result;
    }

    /**
     * 获取签名参数
     *
     * @param outTradeNo 商户网站唯一订单号
     * @param subject    商品名称
     * @param totalFee   总金额
     * @param body       商品详情
     * @return
     */
    private String createParamString(String outTradeNo, String subject, Double totalFee, String body) {
        // 实例化客户端
        AlipayClient alipayClient = new DefaultAlipayClient(gate, AliAppPayConfig.instance().getAppId(),
                AliAppPayConfig.instance().getPrivateKey(), "json", AliAppPayConfig.instance().getCharset(),
                AliAppPayConfig.instance().getPublicKey(), "RSA2");
        // 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        // SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setOutTradeNo(outTradeNo);
        model.setSubject(subject);
        model.setTotalAmount(String.valueOf(totalFee));
        model.setBody(body);
        model.setTimeoutExpress("30m");
        model.setProductCode("QUICK_MSECURITY_PAY");
        request.setBizModel(model);
        request.setNotifyUrl(AliAppPayConfig.instance().getNotifyUrl());
        try {
            // 这里和普通的接口调用不同，使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            logger.info("支付宝支付，获取orderString成功orderString=" + response.getBody());
            return response.getBody();// 就是orderString 可以直接给客户端请求，无需再做处理。
        } catch (AlipayApiException e) {
            logger.info("支付宝支付，获取orderString失败");
            e.printStackTrace();
            return "支付宝支付，获取orderString失败";
        }
    }


    /**
     * 分润推送
     */
    protected void pushAll(String merchantId, String money, String orderId) {
        //推送
        try {
            Merchant merchant = merchantMapper.selectMerchantById(merchantId);
            PaymentOrder paymentOrder = paymentOrderMapper.selectPaymentOrderById(orderId);
            String msg = moenyTypeStatus(paymentOrder.getOrderType());
            String name = paymentOrder.getMerchantName().substring(0, 1);
            Map<String, String> parm = new HashMap<String, String>(16);
            parm.put("id", merchant.getMerchantNo());
            parm.put("msg", name + "**" + msg + paymentOrder.getAmountMoney() + ",分润" + money);
            parm.put("dateTime", DateUtils.getTime());
            JPushUtil.jpushAll(parm);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("极光推送失败,{}", e);
        }
    }


    private String moenyTypeStatus(Integer type) {
        String msg = "";
        if (type.equals(6)) {
            msg = "充值升级";
        } else if (type.equals(9)) {
            msg = "健康检测";
        } else if (type.equals(10)) {
            msg = "境外消费";
        }
        return msg;
    }
}
